/*
 * @lc app=leetcode.cn id=886 lang=cpp
 *
 * [886] 可能的二分法
 *
 * https://leetcode.cn/problems/possible-bipartition/description/
 *
 * algorithms
 * Medium (49.74%)
 * Likes:    276
 * Dislikes: 0
 * Total Accepted:    30.8K
 * Total Submissions: 61.4K
 * Testcase Example:  '4\n[[1,2],[1,3],[2,4]]'
 *
 * 给定一组 n 人（编号为 1, 2, ...,
 * n）， 我们想把每个人分进任意大小的两组。每个人都可能不喜欢其他人，那么他们不应该属于同一组。
 *
 * 给定整数 n 和数组 dislikes ，其中 dislikes[i] = [ai, bi] ，表示不允许将编号为 ai 和
 * bi的人归入同一组。当可以用这种方法将所有人分进两组时，返回 true；否则返回 false。
 *
 *
 *
 *
 *
 *
 * 示例 1：
 *
 *
 * 输入：n = 4, dislikes = [[1,2],[1,3],[2,4]]
 * 输出：true
 * 解释：group1 [1,4], group2 [2,3]
 *
 *
 * 示例 2：
 *
 *
 * 输入：n = 3, dislikes = [[1,2],[1,3],[2,3]]
 * 输出：false
 *
 *
 * 示例 3：
 *
 *
 * 输入：n = 5, dislikes = [[1,2],[2,3],[3,4],[4,5],[1,5]]
 * 输出：false
 *
 *
 *
 *
 * 提示：
 *
 *
 * 1 <= n <= 2000
 * 0 <= dislikes.length <= 10^4
 * dislikes[i].length == 2
 * 1 <= dislikes[i][j] <= n
 * ai < bi
 * dislikes 中每一组都 不同
 *
 *
 *
 *
 */

// @lc code=start
#include <iostream>
#include <vector>
using namespace std;

class Solution {
public:
    bool dfs(int index, vector<int> &vec, int color, vector<vector<int>> &graph) {
        vec[index] = color;
        for (auto &enemy : graph[index]) {
            if (vec[enemy] && vec[enemy] == color) {
                return false;
            }
            if (!vec[enemy] && !dfs(enemy, vec, 3 ^ color, graph)) {
                return false;
            }
        }
        return true;
    }

    bool possibleBipartition(int n, vector<vector<int>> &dislikes) {
        // 建图
        vector<vector<int>> graph(n + 1, vector<int>{});
        for (auto dislike : dislikes) {
            graph[dislike[0]].emplace_back(dislike[1]);
            graph[dislike[1]].emplace_back(dislike[0]);
        }
        // 建染色画布
        vector<int> vec(n + 1, 0);
        for (int i = 1; i <= n; ++i) {
            if (!vec[i] && !dfs(i, vec, 1, graph)) {
                return false;
            }
        }
        return true;
    }
};
// @lc code=end
